﻿using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace Songhay.OpenXml
{
    using Songhay.OpenXml.Extensions;
    using Songhay.OpenXml.Models;

    /// <summary>
    /// Static members for Open XML.
    /// </summary>
    public static partial class OpenXmlUtility
    {
        /// <summary>
        /// Translates the entities.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <param name="settings">The settings.</param>
        /// <remarks>
        /// For more detail, see “Writing Entity References using LINQ to XML”
        ///(http://blogs.msdn.com/b/ericwhite/archive/2010/01/21/writing-entity-references-using-linq-to-xml.aspx)
        /// by Eric White
        /// </remarks>
        public static object TranslateEntities(string text, SonghayHtmlConverterSettings settings)
        {
            if(!settings.UseEntityMap) return text;

            if(text == null) return null;

            object o = text.ToCharArray()
                .GroupAdjacent((char c) =>
                {
                    if(c == 0xf0b7 ||
                        c == 0xf0a7 ||
                        c == 0xf076 ||
                        c == 0xf0d8 ||
                        c == 0xf0a8 ||
                        c == 0xf0fc ||
                        c == 0xf0e0 ||
                        c == 0xf0b2)
                        return "bull";
                    if(c >= 0xf000)
                        return "loz";
                    if(c >= 128)
                    {
                        string entity;
                        if(EntityMap.TryGetValue(c, out entity))
                            return entity;
                    }
                    return "-";
                })
                .Select(g =>
                {
                    if(g.Key != "-")
                        return (object)(g.Select(c => new XEntity(g.Key)));
                    return new XText(g.Aggregate(new StringBuilder(),
                            (s, i) => s.Append(i),
                            s => s.ToString()));
                });
            return o;
        }
    }
}
